//##########################################################################
//#                                                                        #
//#                               CCLIB                                    #
//#                                                                        #
//#  This program is free software; you can redistribute it and/or modify  #
//#  it under the terms of the GNU Library General Public License as       #
//#  published by the Free Software Foundation; version 2 of the License.  #
//#                                                                        #
//#  This program is distributed in the hope that it will be useful,       #
//#  but WITHOUT ANY WARRANTY; without even the implied warranty of        #
//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         #
//#  GNU General Public License for more details.                          #
//#                                                                        #
//#          COPYRIGHT: EDF R&D / TELECOM ParisTech (ENST-TSI)             #
//#                                                                        #
//##########################################################################
//
//*********************** Last revision of this file ***********************
//$Author::                                                                $
//$Rev::                                                                   $
//$LastChangedDate::                                                       $
//**************************************************************************
//

#ifndef GENERIC_CLOUD_HEADER
#define GENERIC_CLOUD_HEADER

#include "CCGeom.h"
#include "CCConst.h"

namespace CCLib
{

//! A generic 3D point cloud interface for data communication between library and client applications

#ifdef CC_USE_AS_DLL
#include "CloudCompareDll.h"

class CC_DLL_API GenericCloud
#else
class GenericCloud
#endif
{

public:

		//! Default destructor
		virtual ~GenericCloud() {};

		//! Generic function applied to a point (used by foreach)
		typedef void genericPointAction(const CCVector3&, DistanceType&);

		//! Returns the number of points
		/**	Virtual method to request the cloud size
			\return the cloud size
		**/
		virtual unsigned size() const = 0;

		//! Fast iteration mechanism
		/**	Virtual method to apply a function to the whole cloud
			\param anAction the function to apply (see GenericCloud::genericPointAction)
		**/
		virtual void forEach(genericPointAction& anAction) = 0;

		//! Returns the cloud bounding box
		/**	Virtual method to request the cloud bounding box limits
			\param Mins a 3 elements array to store the lower BB limits (Xmin,Ymin,Zmin)
			\param Maxs a 3 elements array to store the higher BB limits (Xmax,Ymax,Zmax)
		**/
		virtual void getBoundingBox(PointCoordinateType Mins[], PointCoordinateType Maxs[]) = 0;

		//! Returns a point VISIBILITY
		/**	Generic method to request a point VISIBILITY (should be overloaded if this functionality is needed).
			The point visibility is such as defined in Daniel Girardeau-Montaut's PhD manuscript (see Chapter 2, 
			section 2-3-3). In this case, a ground based laser sensor model should be used to determine it 
			(see GenericSensor, and GroundBasedLidarSensor).
			This method is called before performing any point-to-cloud comparison. If the result is not VIEWED, 
			then the comparison won't be performed and the scalar field value associated to this point will be 
			this visibility value.
			\param P the 3D point to test
			\return visibility (default behavior: VIEWED)
		**/
		virtual CC_VISIBILITY_TYPE testVisibility(const CCVector3& P) const {return VIEWED;};

		//! Sets the cloud iterator at the begining
		/**	Virtual method to handle the cloud global iterator
		**/
		virtual void placeIteratorAtBegining()=0;

		//! Returns the next point (relatively to the global iterator position)
		/**	Virtual method to handle the cloud global iterator.
			Global iterator position should be increased by one each time
			this method is called.
			Warning:
			- the returned object may not be persistent!
			- THIS METHOD MAY NOT BE COMPATIBLE WITH PARALLEL STRATEGIES
			(see the DgmOctree::executeFunctionForAllCellsAtLevel_MT and
			DgmOctree::executeFunctionForAllCellsAtStartingLevel_MT methods).
			\return pointer on next point (or 0 if no more)
		**/
		virtual const CCVector3* getNextPoint()=0;

		//!	Enables the scalar field associated to the cloud
		/** If the scalar field structure is not yet initialized/allocated,
			this method gives the signal for its creation. Otherwise, if possible
			the structure size should be pre-reserved with the same number of
			elements as the point cloud.
		**/
		virtual bool enableScalarField()=0;

		//! Returns true if the scalar field is enabled, false otherwise
		virtual bool isScalarFieldEnabled() const =0;

		//! Sets the ith point associated scalar value
		virtual void setPointScalarValue(unsigned pointIndex, DistanceType value)=0;

		//! Returns the ith point associated scalar value
		virtual DistanceType getPointScalarValue(unsigned pointIndex) const =0;
};

}

#endif
